package org.example.sudoku;

import java.util.Iterator;

import org.example.sudoku.R.string;

import android.R.bool;
import android.R.integer;
import android.app.Activity;
import android.app.Dialog;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.widget.Toast;

public class Game extends Activity {

	static public final String TAG = "Sudoku";
	static public final String KEY_DIFFICULTY = "org.example.sudoku.difficulty";
	static public final int DIFFICULTY_EASY = 0;
	static public final int DIFFICULTY_MEDIUM = 1;
	static public final int DIFFICULTY_HARD = 2;
    private static final String PREF_PUZZLE="puzzle";
    protected static  final int DIFFICULTY_CONTINUE = -1;
	private final String easyPuzzle =
		      "360000000004230800000004200" +
		      "070460003820000014500013020" +
		      "001900000007048300000000045";
		   private final String mediumPuzzle =
		      "650000070000506000014000005" +
		      "007009000002314700000700800" +
		      "500000630000201000030000097";
		   private final String hardPuzzle =
		      "009000000080605020501078000" +
		      "000000700706040102004000000" +
		      "000720903090301080000000600";

	private final int used[][][] = new int[9][9][];

	private int puzzle[] = new int[9 * 9];
	PuzzleView puzzleView;
	

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
	      Log.d(TAG, "onCreate");

	      int diff = getIntent().getIntExtra(KEY_DIFFICULTY,
	            DIFFICULTY_CONTINUE);
	      
	      puzzle = getPuzzle(diff);
	      
	      calculateUsedTiles();
	      puzzleView = new PuzzleView(this);
	      setContentView(puzzleView);
	      puzzleView.requestFocus();
	      
	      
		
	}

	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		
		Music.play(this, R.raw.game);
	}
	
	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		super.onPause();
		Music.stop(this);
		
		getPreferences(MODE_PRIVATE).edit().putString
		(this.PREF_PUZZLE, toPuzzleString(puzzle)).commit();
	}
	private int[] getPuzzle(int diff) {
		String puz = null;
		switch (diff) {
		case DIFFICULTY_EASY:
			puz = easyPuzzle;
			break;
		case DIFFICULTY_MEDIUM:
			puz = mediumPuzzle;
			break;
		case DIFFICULTY_HARD:
			puz = hardPuzzle;
			break;
		case DIFFICULTY_CONTINUE:
			puz = getPreferences(MODE_PRIVATE).getString(PREF_PUZZLE, easyPuzzle);
			break;
		default:
			break;
		}

		return fromPuzzleString(puz);
	}

	static protected int[] fromPuzzleString(String string) {
		int puz[] = new int[string.length()];
		for (int i = 0; i < puz.length; i++) {
			puz[i] = string.charAt(i) - '0';
		}
		return puz;

	}

	static private String toPuzzleString(int[] puz) {
		StringBuilder buf = new StringBuilder();
		for (int element : puz) {
			buf.append(element);
		}
		return buf.toString();
	}

	private int getTitle(int x, int y) {
		return puzzle[y * 9 + x];
	}

	private void setTitle(int x, int y, int value) {
		puzzle[y * 9 + x] = value;
	}

	public String getTileString(int x, int y) {
		int v = getTitle(x, y);
		if (v == 0) {
			return "";

		} else
			return String.valueOf(v);
	}

	private int[] calculateUsedTiles(int x, int y) {
		 int c[] = new int[9];
	      // horizontal
	      for (int i = 0; i < 9; i++) { 
	         if (i == x)
	            continue;
	         int t = getTitle(i, y);
	         if (t != 0)
	            c[t - 1] = t;
	      }

		 // vertical
	      for (int i = 0; i < 9; i++) { 
	         if (i == y)
	            continue;
	         int t = getTitle(x, i);
	         if (t != 0)
	            c[t - 1] = t;
	      }

		 // same cell block
	      int startx = (x / 3) * 3; 
	      int starty = (y / 3) * 3;
	      for (int i = startx; i < startx + 3; i++) {
	         for (int j = starty; j < starty + 3; j++) {
	            if (i == x && j == y)
	               continue;
	            int t = getTitle(i, j);
	            if (t != 0)
	               c[t - 1] = t;
	         }
	      }
	      // compress
	      int nused = 0; 
	      for (int t : c) {
	         if (t != 0)
	            nused++;
	      }
	      int c1[] = new int[nused];
	      nused = 0;
	      for (int t : c) {
	         if (t != 0)
	            c1[nused++] = t;
	      }
	      return c1;
	}
   


	private void calculateUsedTiles() {
		for (int x = 0; x < 9; x++) {
			for (int y = 0; y < 9; y++) {
				used[x][y] = calculateUsedTiles(x, y);
				
			}
		}
	}

	public int[] getUsedTitles(int x, int y) {
		return used[x][y];
	}

	public boolean setTitleIfValid(int x, int y, int value) {
		int titles[] = getUsedTitles(x, y);
		if (value != 0) {
			for (int title : titles) {
				if (title == value)
					return false;
			}

		}
		setTitle(x, y, value);
		calculateUsedTiles();
		return true;

	}

	public void showKeypadOrError(int x, int y) {
		int tites[] = getUsedTitles(x, y);
		if (tites == null)
			return;

		if (tites.length == 9) {
			Toast toast = Toast.makeText(this, R.string.no_moves_label,
					Toast.LENGTH_SHORT);
			toast.setGravity(Gravity.CENTER, 0, 0);
			toast.show();
		} else {
			 Log.d(TAG, "showKeypad:used="+toPuzzleString(tites));
			Dialog dialog = new Keypad(this, tites, puzzleView);
			dialog.show();

		}

	}
}
